package com.atguigu.a_principle.p5openclose.v2;

/**
 * 开闭原则
 * 1. 一个软件实体如类，模块和函数应该对扩展开放(对提供方)，对修改关闭(对使用方)。用抽象构建框架，用实
 * 现扩展细节。
 * 2。当软件需要变化时，尽量通过扩展软件实体的行为来实现变化，而不是通过修改已有的代码来实现变化。
 */
public class OpenClose {

    public static void main(String[] args) {
        Circle circle = new Circle();
        Rectangle rectangle = new Rectangle();
        GraphicEditor graphicEditor = new GraphicEditor();
        Triangle triangle = new Triangle();
        graphicEditor.drawShape(circle);
        graphicEditor.drawShape(rectangle);
        graphicEditor.drawShape(triangle);
    }
//    方式 1 的优缺点
    /*
    * 1.优点是比较好理解，简单易操作。
    * 2.缺点是违反了设计模式的 ocp 原则，即对扩展开放(提供方)，对修改关闭(使用方)。
    * 即当我们给类增加新功能的时候，尽量不修改代码，或者尽可能少修改代码.
    * 3.比如我们这时要新增加一个图形种类 三角形，我们需要做如下修改，修改的地方较多
    * */

//    方式 1 的改进的思路分析
/**
 * 把创建 Shape 类做成抽象类，并提供一个抽象的 draw 方法，让子类去实现即可，这样我们有新的图形种类时，
 * 只需要让新的图形类继承 Shape，并实现 draw 方法即可，使用方的代码就不需要修 -> 满足了开闭原则*/
}

class GraphicEditor {
    public void drawShape(Shapes shape){
        shape.drawShape();
    }
}

 abstract class Shapes {
    int mType;
    public abstract void drawShape();
}

class Rectangle extends Shapes{
    public Rectangle() {
        super.mType=1;
    }

    @Override
    public void drawShape() {
        System.out.println("绘制矩形形");
    }
}

class Circle extends Shapes {
    public Circle() {
        super.mType=2;
    }

    @Override
    public void drawShape() {
        System.out.println("绘制圆形形");
    }
}

//新增画三角形
class Triangle extends Shapes {
    Triangle() {
        super.mType = 3;
    }
    @Override
    public void drawShape() {
        System.out.println("绘制三角形形");
    }
}